home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / nt / chmod.nt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  10.0 KB  |  431 lines

  1. /* Chmod command for Windows NT operating system
  2.  
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.  
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.  
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
  16.  
  17.  Notes:
  18.      - Preliminar. Work to be done here. (Maybe should write a command to
  19.         change attributes and another to change rwx permissions.
  20.  */
  21. #ifndef _OS_NT
  22. #error This file is for the NT operating system.
  23. #else
  24.  
  25. #include <config.h>
  26. #include <windows.h>
  27. #include <string.h>
  28. #include <stdio.h>
  29. #include "tty.h"
  30. #include "mad.h"
  31. #include "util.h"
  32. #include "win.h"
  33. #include "color.h"
  34. #include "dlg.h"
  35. #include "widget.h"
  36. #include "dialog.h"    /* For do_refresh() */
  37.  
  38. #include "dir.h"
  39. #include "panel.h"        /* Needed for the externs */
  40. #include "file.h"
  41. #include "main.h"
  42. #include "chmod.h"
  43. #include "achown.h"
  44. #include "chown.h"
  45.  
  46. static int single_set;
  47. struct Dlg_head *ch_dlg;
  48.  
  49. #define PX        5
  50. #define PY        2
  51.  
  52. #define FX        40
  53. #define FY        2
  54.  
  55. #define BX        6
  56. #define BY        17
  57.  
  58. #define TX        40
  59. #define TY        12
  60.  
  61. #define PERMISSIONS    4 
  62. #define BUTTONS        6
  63.  
  64. #define B_MARKED    B_USER
  65. #define B_ALL        B_USER+1
  66. #define B_SETMRK        B_USER+2
  67. #define B_CLRMRK        B_USER+3
  68.  
  69. int mode_change, need_update;
  70. int c_file, end_chmod;
  71.  
  72. umode_t and_mask, or_mask, c_stat;
  73. char *c_fname, *c_fown, *c_fgrp, *c_fperm;
  74. int c_fsize;
  75.  
  76. static WLabel *statl;
  77. static int normal_color;
  78. static int title_color;
  79. static int selection_color;
  80.  
  81. struct {
  82.     mode_t mode;
  83.     char *text;
  84.     int selected;
  85.     WCheck *check;
  86. } check_perm[PERMISSIONS] = {
  87.  
  88.     {    
  89.     FILE_ATTRIBUTE_ARCHIVE, "Archive", 0, 0,
  90.     },
  91.     {
  92.     FILE_ATTRIBUTE_READONLY, "Read Only", 0, 0,
  93.     },
  94.     {
  95.     FILE_ATTRIBUTE_HIDDEN, "Hidden", 0, 0,
  96.     },
  97.     {
  98.     FILE_ATTRIBUTE_SYSTEM, "System", 0, 0,
  99.     },
  100. /*    {
  101.     S_IWGRP, "write by group", 0, 0,
  102.     },
  103.     {
  104.     S_IRGRP, "read by group", 0, 0,
  105.     },
  106.     {
  107.     S_IXUSR, "execute/search by owner", 0, 0,
  108.     },
  109.     {
  110.     S_IWUSR, "write by owner", 0, 0,
  111.     },
  112.     {
  113.     S_IRUSR, "read by owner", 0, 0,
  114.     },
  115. */
  116. };
  117.  
  118. struct {
  119.     int ret_cmd, y, x;
  120.     char *text;
  121.     int hkey, hpos;
  122. } chmod_but[BUTTONS] = {
  123.  
  124.     {
  125.     B_CANCEL, 2, 33, "[ Cancel ]", 'c', 2,
  126.     },
  127.     {
  128.     B_ENTER, 2, 17, "[ Set ]", 's', 2,
  129.     },
  130.     {
  131.     B_CLRMRK, 0, 42, "[ Clear marked ]", 'l', 3,
  132.     },
  133.     {
  134.     B_SETMRK, 0, 27, "[ Set marked ]", 'e', 3,
  135.     },
  136.     {
  137.     B_MARKED, 0, 12, "[ Marked all ]", 'm', 2,
  138.     },
  139.     {
  140.     B_ALL, 0, 0, "[ Set all ]", 'a', 6,
  141.     },
  142. };
  143.  
  144. static void chmod_toggle_select (void)
  145. {
  146.     int Id = ch_dlg->current->dlg_id - BUTTONS + single_set * 2;
  147.  
  148.     attrset (normal_color);
  149.     check_perm[Id].selected ^= 1;
  150.  
  151.     dlg_move (ch_dlg, PY + PERMISSIONS - Id, PX + 1);
  152.     addch ((check_perm[Id].selected) ? '*' : ' ');
  153.     dlg_move (ch_dlg, PY + PERMISSIONS - Id, PX + 3);
  154. }
  155.  
  156. static void chmod_refresh (void)
  157. {
  158.     attrset (normal_color);
  159.     dlg_erase (ch_dlg);
  160.     
  161.     draw_box (ch_dlg, 1, 2, 20 - single_set, 66);
  162.     draw_box (ch_dlg, PY, PX, PERMISSIONS + 2, 33);
  163.     draw_box (ch_dlg, FY, FX, 10, 25);
  164.  
  165.     dlg_move (ch_dlg, FY + 1, FX + 2);
  166.     addstr ("Name");
  167.     dlg_move (ch_dlg, FY + 3, FX + 2);
  168.     addstr ("Permissions (Octal)");
  169.     dlg_move (ch_dlg, FY + 5, FX + 2);
  170.     addstr ("Owner name");
  171.     dlg_move (ch_dlg, FY + 7, FX + 2);
  172.     addstr ("Group name");
  173.     
  174.     attrset (title_color);
  175.     dlg_move (ch_dlg, 1, 28);
  176.     addstr (" Chmod command ");
  177.     dlg_move (ch_dlg, PY, PX + 1);
  178.     addstr (" Permission ");
  179.     dlg_move (ch_dlg, FY, FX + 1);
  180.     addstr (" File ");
  181.     
  182.     attrset (selection_color);
  183.  
  184.     dlg_move (ch_dlg, TY, TX);
  185.     addstr ("Use SPACE to change");
  186.     dlg_move (ch_dlg, TY + 1, TX);
  187.     addstr ("an option, ARROW KEYS");
  188.     dlg_move (ch_dlg, TY + 2, TX);
  189.     addstr ("to move between options");
  190.     dlg_move (ch_dlg, TY + 3, TX);
  191.     addstr ("and T or INS to mark");
  192. }
  193.  
  194. static int chmod_callback (Dlg_head *h, int Par, int Msg)
  195. {
  196.     char buffer [10];
  197.     
  198.     switch (Msg) {
  199.     case DLG_ACTION:
  200.     if (Par >= BUTTONS - single_set * 2){
  201.         c_stat ^= check_perm[Par - BUTTONS + single_set * 2].mode;
  202.         sprintf (buffer, "%o", c_stat);
  203.         label_set_text (statl, buffer);
  204.         chmod_toggle_select ();
  205.         mode_change = 1;
  206.     }
  207.     break;
  208.  
  209.     case DLG_KEY:
  210.     if ((Par == 'T' || Par == 't' || Par == KEY_IC) &&
  211.         ch_dlg->current->dlg_id >= BUTTONS - single_set * 2) {
  212.         chmod_toggle_select ();
  213.         if (Par == KEY_IC)
  214.         dlg_one_down (ch_dlg);
  215.         return 1;
  216.     }
  217.     break;
  218. #ifndef HAVE_X
  219.     case DLG_DRAW:
  220.     chmod_refresh ();
  221.     break;
  222. #endif
  223.     }
  224.     return 0;
  225. }
  226.  
  227. static void init_chmod (void)
  228. {
  229.     int i;
  230.  
  231.     do_refresh ();
  232.     end_chmod = c_file = need_update = 0;
  233.     single_set = (cpanel->marked < 2) ? 2 : 0;
  234.  
  235.     if (use_colors){
  236.     normal_color = COLOR_NORMAL;
  237.     title_color  = COLOR_HOT_NORMAL;
  238.     selection_color = COLOR_NORMAL;
  239.     } else {
  240.     normal_color = NORMAL_COLOR;
  241.     title_color  = SELECTED_COLOR;
  242.     selection_color = SELECTED_COLOR;
  243.     }
  244.     
  245.     ch_dlg = create_dlg (0, 0, 22 - single_set, 70, dialog_colors,
  246.              chmod_callback, "[Chmod]", "chmod", DLG_CENTER);
  247.              
  248.     x_set_dialog_title (ch_dlg, "Chmod command");
  249.  
  250. #define XTRACT(i) BY+chmod_but[i].y-single_set, BX+chmod_but[i].x, \
  251.                   chmod_but[i].ret_cmd, chmod_but[i].text, chmod_but[i].hkey,                    chmod_but[i].hpos, 0, 0
  252.  
  253.     tk_new_frame (ch_dlg, "b.");
  254.     for (i = 0; i < BUTTONS; i++) {
  255.     if (i == 2 && single_set)
  256.         break;
  257.     else
  258.         add_widgetl (ch_dlg, button_new (XTRACT (i)), XV_WLAY_RIGHTOF);
  259.     }
  260.  
  261.  
  262. #define XTRACT2(i) 0, check_perm [i].text, 0,-1
  263.     tk_new_frame (ch_dlg, "c.");
  264.     for (i = 0; i < PERMISSIONS; i++) {
  265.     check_perm[i].check = check_new (PY + (PERMISSIONS - i), PX + 2,
  266.                      XTRACT2 (i));
  267.     add_widget (ch_dlg, check_perm[i].check);
  268.     }
  269. }
  270.  
  271. static int stat_file (char *filename, struct stat *st)
  272. {
  273. // Note: - we assume attribute values fit in st.st_mode (a word, not a dword)
  274. //     - we change st_mode value with attributes, not RWX permissions
  275.  
  276.     if (stat (filename, st))
  277.     return 0;
  278.     st->st_mode = GetFileAttributes (filename);
  279.  
  280.     if (st->st_mode & FILE_ATTRIBUTE_DIRECTORY)
  281.         return 0;
  282.     return 1;
  283. }
  284.  
  285. static void chmod_done (void)
  286. {
  287.     if (need_update)
  288.     update_panels (UP_OPTIMIZE, UP_KEEPSEL, UP_KEEPSEL);
  289.     repaint_screen ();
  290. }
  291.  
  292. char *next_file (void)
  293. {
  294.     while (!cpanel->dir.list[c_file].f.marked)
  295.     c_file++;
  296.  
  297.     return cpanel->dir.list[c_file].fname;
  298. }
  299.  
  300. static void do_chmod (struct stat *sf)
  301. {
  302.     sf->st_mode &= and_mask;
  303.     sf->st_mode |= or_mask;
  304.     SetFileAttributes (cpanel->dir.list [c_file].fname, sf->st_mode);
  305.     file_mark (cpanel, c_file, 0);
  306. }
  307.  
  308. static void apply_mask (struct stat *sf)
  309. {
  310.     char *fname;
  311.  
  312.     need_update = end_chmod = 1;
  313.     do_chmod (sf);
  314.     cpanel->marked--;
  315.  
  316.     do {
  317.     fname = next_file ();
  318.     if (!stat_file (fname, sf))
  319.         return;
  320.     c_stat = sf->st_mode;
  321.  
  322.     do_chmod (sf);
  323.     cpanel->marked--;
  324.     } while (cpanel->marked);
  325. }
  326.  
  327. void chmod_cmd (void)
  328. {
  329.     char buffer [10];
  330.     char *fname;
  331.     int i;
  332.     struct stat sf_stat;
  333.  
  334.     do {            /* do while any files remaining */
  335.     init_chmod ();
  336.     if (cpanel->marked)
  337.         fname = next_file ();    /* next marked file */
  338.     else
  339.         fname = selection (cpanel)->fname;    /* single file */
  340.  
  341.     if (!stat_file (fname, &sf_stat))    /* get status of file */
  342.         break;
  343.     
  344.     c_stat = sf_stat.st_mode;
  345.     mode_change = 0;    /* clear changes flag */
  346.  
  347.     /* set check buttons */
  348.     for (i = 0; i < PERMISSIONS; i++){
  349.         check_perm[i].check->state = (c_stat & check_perm[i].mode) ? 1 : 0;
  350.         check_perm[i].selected = 0;
  351.     }
  352.  
  353.     tk_new_frame (ch_dlg, "l.");
  354.     /* Set the labels */
  355.     c_fname = name_trunc (fname, 21);
  356.     add_widget (ch_dlg, label_new (FY+2, FX+2, c_fname));
  357.     c_fown = name_trunc (get_owner (sf_stat.st_uid), 21);
  358.     add_widget (ch_dlg, label_new (FY+6, FX+2, c_fown));
  359.     c_fgrp = name_trunc (get_group (sf_stat.st_gid), 21);
  360.     add_widget (ch_dlg, label_new (FY+8, FX+2, c_fgrp));
  361.     sprintf (buffer, "%o", c_stat);
  362.     statl = label_new (FY+4, FX+2, buffer);
  363.     add_widget (ch_dlg, statl);
  364.     tk_end_frame ();
  365.     
  366.     run_dlg (ch_dlg);    /* retrieve an action */
  367.     
  368.     /* do action */
  369.     switch (ch_dlg->ret_value){
  370.     case B_ENTER:
  371.         if (mode_change)
  372.         chmod (fname, c_stat);
  373.         need_update = 1;
  374.         break;
  375.         
  376.     case B_CANCEL:
  377.         end_chmod = 1;
  378.         break;
  379.         
  380.     case B_ALL:
  381.     case B_MARKED:
  382.         and_mask = or_mask = 0;
  383.         and_mask = ~and_mask;
  384.  
  385.         for (i = 0; i < PERMISSIONS; i++) {
  386.         if (check_perm[i].selected || ch_dlg->ret_value == B_ALL)
  387.             if (check_perm[i].check->state & C_BOOL)
  388.             or_mask |= check_perm[i].mode;
  389.             else
  390.             and_mask &= ~check_perm[i].mode;
  391.         }
  392.  
  393.         apply_mask (&sf_stat);
  394.         break;
  395.         
  396.     case B_SETMRK:
  397.         and_mask = or_mask = 0;
  398.         and_mask = ~and_mask;
  399.  
  400.         for (i = 0; i < PERMISSIONS; i++) {
  401.         if (check_perm[i].selected)
  402.             or_mask |= check_perm[i].mode;
  403.         }
  404.  
  405.         apply_mask (&sf_stat);
  406.         break;
  407.     case B_CLRMRK:
  408.         and_mask = or_mask = 0;
  409.         and_mask = ~and_mask;
  410.  
  411.         for (i = 0; i < PERMISSIONS; i++) {
  412.         if (check_perm[i].selected)
  413.             and_mask &= ~check_perm[i].mode;
  414.         }
  415.  
  416.         apply_mask (&sf_stat);
  417.         break;
  418.     }
  419.  
  420.     if (cpanel->marked && ch_dlg->ret_value!=B_CANCEL) {
  421.         file_mark (cpanel, c_file, 0);
  422.         cpanel->marked--;
  423.         need_update = 1;
  424.     }
  425.     destroy_dlg (ch_dlg);
  426.     } while (cpanel->marked && !end_chmod);
  427.     chmod_done ();
  428. }
  429.  
  430. #endif /*_OS_NT*/
  431.